from django.http import JsonResponse, HttpResponse
from . import models
# from django.core import serializers
from . import serializers
# import json
import pprint
from state.models import Account
from django_redis import get_redis_connection
from .utils import change_last_score_value
import json


# Create your views here.


def find_music_by_type(request, music_type):
    """
    通过歌曲的分类查询歌曲
    :param request: http://localhost:8000/music/type/爱情/
    :param music_type:爱情
    :return:{
                "data": [{"music_name": " ", "music_signer_name": " ", "music_duration": ,}, {}, {}],
                "status": 200,
                "message":
            }
    """
    # 模糊查询
    # print(f"type:{music_type}")
    try:
        musics_queryset = models.Music.objects.filter(music_type__contains=music_type)
        # musics_json = serializers.serialize("json", musics_queryset)
        musics_dict = serializers.MusicSerializer(musics_queryset, many=True).data
        # print(musics_dict)
        data = {
            "data": musics_dict,
            "status": 200,
            "message": "查询成功3"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)
    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def find_singer_by_type_and_gender(request, singer_type, singer_gender):
    """
    通过歌手的国籍和歌手的性别查询歌手
    :param request: http://localhost:8000/music/singer/中国/m/
    :param singer_type: 中国
    :param singer_gender: m
    :return:{
            "data":[{"singer_name": " ", "signer_img_add": " ", }, {}, {}],
            "status": 200,
            "message": "查询成功4"
        }
    """
    # print(f"singer_gender:{singer_gender}")
    try:
        if singer_gender == " ":
            print("歌手性别为空")
            singers_queryset = models.Singer.objects.filter(singer_type=singer_type)
        else:
            singers_queryset = models.Singer.objects.filter(singer_type=singer_type, singer_gender=singer_gender)
        singers_dict = serializers.SingerSerializer(singers_queryset, many=True).data
        data = {
            "data": singers_dict,
            "status": 200,
            "message": "查询成功4"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)
    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def find_music_by_singer(request, singer_name):
    """
    通过歌手名查询歌曲
    :param request: http://localhost:8000/music/singer/music/陈奕迅/
    :param singer_name:陈奕迅
    :return:{
            "data": [{"music_name": " ", "music_signer_name": " ", "music_duration": ,}, {}, {}],
            "status": 200,
            "message": "查询成功5"
        }
    """
    # 模糊查询
    try:
        musics_queryset = models.Music.objects.filter(music_singer_name__contains=singer_name)
        musics_dict = serializers.MusicSerializer(instance=musics_queryset, many=True).data
        data = {
            "data": musics_dict,
            "status": 200,
            "message": "查询成功5"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)
    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def query_all_singer(request):
    """
    查询所有歌手
    :param request:http://localhost:8000/music/singer/all/
    :return:{
            "data":[{"singer_name": " ", "signer_img_add": " ", }, {}, {}],
            "status": 200,
            "message": "查询成功6"
        }
    """
    try:
        singers_queryset = models.Singer.objects.all()
        singers_dict = serializers.SingerSerializer(instance=singers_queryset, many=True).data
        data = {
            "data": singers_dict,
            "status": 200,
            "message": "查询成功7"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)

    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def search_music_by_music_pinshou(request, music_pinshou):
    """
    通过歌曲名拼音缩写搜索歌曲
    :param request: http://localhost:8000/music/search/music/X/
    :param music_pinshou:X
    :return:{
            "data": [{"music_name": " ", "music_signer_name": " ", "music_duration": ,}, {}, {}],
            "status": 200,
            "message": "查询成功"
        }
    """
    print(music_pinshou)
    # 模糊查询
    try:
        musics_queryset = models.Music.objects.filter(music_pinshou__istartswith=music_pinshou)
        # print(musics_queryset)
        # print(musics_dict)
        if musics_queryset:
            musics_dict = serializers.MusicSerializer(musics_queryset, many=True).data
            data = {
                "data": musics_dict,
                "status": 200,
                "message": "查询成功8"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
        else:
            data = {
                "status": 403,
                "message": "没有您要的歌曲，您可以把想要的歌曲提交给我们"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def search_music_by_singer_pinshou(request, singer_pinshou):
    """
    通过歌手拼音缩写搜索歌曲
    :param request: http://localhost:8000/music/search/singer/CYX/
    :param singer_pinshou:CYX
    :return:{
            "data": [{"music_name": " ", "music_signer_name": " ", "music_duration": ,}, {}, {}],
            "status": 200,
            "message": "查询成功1"
        }
    """
    # 模糊查询
    try:
        musics_queryset = models.Music.objects.filter(music_singer_detail__signer_pinshou__istartswith=singer_pinshou)
        if musics_queryset:
            musics_dict = serializers.MusicSerializer(musics_queryset, many=True).data
            data = {
                "data": musics_dict,
                "status": 200,
                "message": "查询成功2"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
        else:
            data = {
                "status": 403,
                "message": "没有您要的歌手，您可以把想要的歌手提交给我们"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def login(request):
    """
    K歌账号登录
    :param request: http://127.0.0.1:8000/music/login/
    :return:data = {
                    "status": 200,
                    "message": "登录成功"
                }

    """
    print(request.method)

    if request.method == "POST":
        # 获取登录账号信息

        params = request.body.decode("utf-8")
        params_dict = json.loads(params)
        account_username = params_dict.get("account_username")
        account_pwd = params_dict.get("account_pwd")
        # print(params)

        print(account_username, account_pwd)

        try:
            account = Account.objects.filter(account_username=account_username, account_pwd=account_pwd)
            if account:
                # 登录业务处理
                request.session["account_username"] = account_username
                data = {
                    "status": 200,
                    "message": "登录成功"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
            else:
                data = {
                    "status": 403,
                    "message": "您的账号或密码错误，请重试"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
        except Exception as e:
            print(e)
            data = {
                "status": 404,
                "message": "网络开小差了，请重新尝试"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
    else:
        data = {
            "status": 405,
            "message": f"禁止使用{request.method}请求"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def logout(request):
    """
    退出K歌账号
    :param request:http://127.0.0.1:8000/music/logout/
    :return:data = {
                "status": 204,
                "message": "账号退出成功"
            }
    """
    if request.method == "DELETE":
        try:
            account_username = request.session.get("account_username")
            if account_username is None:
                data = {
                    "status": 403,
                    "message": "您未登录，请登录后操作"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
            redis_client = get_redis_connection("playlist")
            redis_client.zremrangebyrank(account_username, 0, -1)
            redis_client.delete(f"{account_username}-last_score")
            request.session.flush()
            data = {
                "status": 204,
                "message": "账号退出成功"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
        except Exception as e:
            print(e)
            data = {
                "status": 404,
                "message": "网络开小差了，请重新尝试"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
    else:
        data = {
            "status": 405,
            "message": f"禁止使用{request.method}方式请求"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def add_music_to_playlist(request, music_name, music_singer_name, music_duration):
    """
    将音乐添加到播放列表中
    :param request:http://127.0.0.1:8000/music/playlist/order/兄弟难当/杜歌/4:20/
    :param music_name:兄弟难当
    :param music_singer_name:杜歌
    :param music_duration:4:20
    :return:data = {
                "status": 201,
                "message": "添加成功"
            }
    """
    if request.method == "POST":
        try:
            # 获取session
            account_username = request.session.get("account_username")
            # print(f"type(account_username):{type(account_username)}")
            print(account_username)
            if account_username is None:
                data = {
                    "status": 403,
                    "message": "您未登录，请登录后操作"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
            # 连接redis
            redis_client = get_redis_connection("playlist")
            # print("redis连接")
            # 新增一个键用来存储最后一个成员的分数，key:account_id-last_score value:
            # 存储方式:zset, 存储格式：key:account_username  value:music_name-music_singer_name-music_duration

            # redis_client.setnx(f"{account_username}-last_score", 0)  # 如果键不存在，设置为0,这种方式添加后0为字节类型

            # score = redis_client.get(f"{account_username}-last_score")
            # print(f"type(score):{type(score)}")
            score = redis_client.incr(f"{account_username}-last_score")
            redis_client.zadd(name=account_username, mapping={f"{music_name}-{music_singer_name}-{music_duration}": score})
            # redis_client.save()
            data = {
                "status": 201,
                "message": "添加成功"
            }
            # 将数据库中相应的歌曲点击数加1
            music = models.Music.objects.get(music_name=music_name, music_singer_name=music_singer_name)
            music.music_count += 1
            music.save()
            pprint.pprint(data)
            return JsonResponse(data=data)

        except Exception as e:
            print(e)
            data = {
                "status": 404,
                "message": "网络开小差了，请重新尝试"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
    else:
        data = {
            "status": 405,
            "message": f"禁止使用{request.method}方式请求"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def move_music_in_playlist_up(request, music_name, music_singer_name, music_duration):
    """
    将播放列表中指定的歌曲移到第2位
    :param request: http://127.0.0.1:8000/music/playlist/upper/兄弟难当/杜歌/4:20/
    :param music_name:兄弟难当
    :param music_singer_name:杜歌
    :param music_duration:4:20
    :return:data = {
                "status": 202,
                "message": "操作成功"
            }
    """
    if request.method == "POST":
        try:
            # 获取session
            account_username = request.session.get("account_username")
            if account_username is None:
                data = {
                    "status": 403,
                    "message": "您未登录，请登录后操作"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
            # print(f"type(account_username):{type(account_username)}")

            # 连接redis
            redis_client = get_redis_connection("playlist")

            # 获取播放列表中第一个歌曲的value和score
            playlist_first_data = redis_client.zrevrange(account_username, -1, -1, True)
            playlist_first_value, playlist_first_score = playlist_first_data[0][0], playlist_first_data[0][1]
            # 播放列表中第一个歌曲的score-1
            redis_client.zincrby(account_username, -1, playlist_first_value)
            # 将指定歌曲的分数设为score
            redis_client.zadd(account_username, mapping={f"{music_name}-{music_singer_name}-{music_duration}": playlist_first_score})
            # 如果要修改的歌曲是最后一个，重新设置last_score的值
            change_last_score_value(account_username)

            # 获取
            # test_score = redis_client.zscore(account_username, f"{music_name}-{music_singer_name}-{music_duration}")
            # print(f"type(test_score):{type(test_score)}")
            # print(playlist_first_data)
            data = {
                "status": 202,
                "message": "操作成功"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)

        except Exception as e:
            print(e)
            data = {
                "status": 404,
                "message": "网络开小差了，请重新尝试"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)

    else:
        data = {
            "status": 405,
            "message": f"禁止使用{request.method}方式请求"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def show_playlist(request):
    """
    查询播放列表
    :param request:http://localhost:8000/music/playlist/show/
    :return:{
            "data": [{"music_name": " ", "music_signer_name": " ", "music_duration": ,}, {}, {}],
            "status": 200,
            "message": "查询成功5"
        }
    """
    try:
        account_username = request.session.get("account_username")
        print(f"account_username:{account_username}")
        redis_client = get_redis_connection("playlist")
        musics_list = redis_client.zrange(account_username, 0, -1)
        musics_list = [str(music, encoding="utf-8") for music in musics_list]
        musics_list = list(map(lambda x: {"music_name": x.split("-")[0], "music_singer_name": x.split("-")[1], "music_duration": x.split("-")[2]}, musics_list))
        data = {
            "data": musics_list,
            "status": 200,
            "message": "查询成功"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)

    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def del_music_in_playlist(request, music_name, music_singer_name, music_duration):
    """
    将播放列表中指定歌曲删除
    :param request: http://127.0.0.1:8000/music/playlist/del/music/兄弟难当/杜歌/4:20/
    :param music_name: 兄弟难当
    :param music_singer_name: 杜歌
    :param music_duration: 4:20
    :return: data = {
                "status": 202,
                "message": "操作成功"
            }
    """
    if request.method == "DELETE":
        try:
            account_username = request.session.get("account_username")
            if account_username is None:
                data = {
                    "status": 403,
                    "message": "您未登录，请登录后操作"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
            redis_client = get_redis_connection("playlist")
            redis_client.zrem(account_username, f"{music_name}-{music_singer_name}-{music_duration}")
            # 如果要删除的歌曲是最后一个，重新设置last_score的值
            change_last_score_value(account_username)
            data = {
                "status": 202,
                "message": "操作成功"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
        except Exception as e:
            print(e)
            data = {
                "status": 404,
                "message": "网络开小差了，请重新尝试"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)

    else:
        data = {
            "status": 405,
            "message": f"禁止使用{request.method}方式请求"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def del_musics_in_playlist(request):
    """
    删除播放列表中所有的歌曲
    :param request:http://localhost:8000/music/playlist/del/musics/all/
    :return:data = {
                "status": 202,
                "message": "操作成功"
            }
    """
    if request.method == "DELETE":
        try:
            account_username = request.session.get("account_username")
            if account_username is None:
                data = {
                    "status": 403,
                    "message": "您未登录，请登录后操作"
                }
                pprint.pprint(data)
                return JsonResponse(data=data)
            redis_client = get_redis_connection("playlist")
            redis_client.zremrangebyrank(account_username, 0, -1)
            redis_client.delete(f"{account_username}-last_score")
            data = {
                "status": 202,
                "message": "操作成功"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
        except Exception as e:
            print(e)
            data = {
                "status": 404,
                "message": "网络开小差了，请重新尝试"
            }
            pprint.pprint(data)
            return JsonResponse(data=data)
    else:
        data = {
            "status": 405,
            "message": f"禁止使用{request.method}方式请求"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)


def play(request, music_name, music_singer_name):
    """
    播放音乐
    :param request: http://localhost:8000/music/play/兄弟难当/杜歌/
    :param music_singer_name:
    :param music_name:
    :return:
    """
    # 从数据库中获取歌曲文件存储的地址
    try:
        music = models.Music.objects.get(music_name=music_name, music_singer_name=music_singer_name)
        # file_url = "http://qum86h20f.hn-bkt.clouddn.com/music/%E6%9D%9C%E6%AD%8C%20-%20%E5%85%84%E5%BC%9F%E9%9A%BE%E5%BD%93.mp4"
        data = {
                        "status": 200,
                        "message": "获取成功",
                        "music_file_add": music.music_file_add
                    }
        pprint.pprint(data)
        return JsonResponse(data)
    except Exception as e:
        print(e)
        data = {
            "status": 404,
            "message": "网络开小差了，请重新尝试"
        }
        pprint.pprint(data)
        return JsonResponse(data=data)



































